using System;
using Extensions.FPMath;
using Game.Config;
using UnityEngine.Serialization;

namespace Game.Core
{
    [Serializable]
    public unsafe struct PropertyInfo
    {
        public float Strength; // 力量
        public float Dexterity; // 敏捷
        public float Constitution; // 体质
        public float Intellectual; // 智力
        public float Lucky; // 幸运
        public float Charisma; // 魅力
        
        
        public float MaxHealthPoint; // 最大生命值
        public float HealthRecover; // 生命回复
        public float AbilityPower; // 法术强度
        public float MaxAbilityPoint; // 最大法术值
        public float AbilityRecover; // 法术回复
        public float AttackRange; // 攻击范围
        public float AttackSpeed; // 攻击速度
        public float AttackInterval; // 攻击间隔
        public float MinMeleeAttack; // 近战最小攻击
        public float MaxMeleeAttack; // 近战最大攻击
        public float MinRangeAttack; // 远程最小攻击
        public float MaxRangeAttack; // 远程最大攻击
        public float Armor; // 护甲
        public float Resistance; // 抵抗
        public float Penetration; // 穿透
        public float Block; // 格挡
        public float Dodge; // 闪避
        public float Hit; // 命中
        public float CritRate; // 暴击几率
        public float CritRatio; // 暴击比例
        public float Resilience; // 韧性
        public float ExtraDamage; // 真实伤害
        
        
        public float MaxEncumbered; // 负重
        public float MaxTroops; // 最大带兵数量
        public float MoveSpeed; // 移动速度

        public static PropertyInfo operator +(PropertyInfo a) => a;

        public static PropertyInfo operator -(PropertyInfo a) =>
            new PropertyInfo()
            {
                Strength = -a.Strength,
                Dexterity = -a.Dexterity,
                Constitution = -a.Constitution,
                Intellectual = -a.Intellectual,
                Lucky = -a.Lucky,
                Charisma = -a.Charisma,
                
                MaxEncumbered = -a.MaxEncumbered,
                MaxHealthPoint = -a.MaxHealthPoint,
                HealthRecover = -a.HealthRecover,
                AbilityPower = -a.AbilityPower,
                MaxAbilityPoint = -a.MaxAbilityPoint,
                AbilityRecover = -a.AbilityRecover,
                AttackRange = -a.AttackRange,
                AttackSpeed = -a.AttackSpeed,
                AttackInterval = -a.AttackInterval,
                MinMeleeAttack = -a.MinMeleeAttack,
                MaxMeleeAttack = -a.MaxMeleeAttack,
                MinRangeAttack = -a.MinRangeAttack,
                MaxRangeAttack = -a.MaxRangeAttack,
                Armor = -a.Armor, 
                Resistance = -a.Resistance,
                Penetration = -a.Penetration,
                Block = -a.Block,
                Dodge = -a.Dodge,
                Hit = -a.Hit,
                CritRate = -a.CritRate,
                CritRatio = -a.CritRatio,
                Resilience = -a.Resilience,
                ExtraDamage = -a.ExtraDamage,
                
                MaxTroops = -a.MaxTroops,
                MoveSpeed = -a.MoveSpeed,
            };

        public PropertyInfo Add(PropertyInfo* p)
        {
            PropertyInfo r = new PropertyInfo();
            r.Strength = Strength + p->Strength;
            r.Dexterity = Dexterity + p->Dexterity;
            r.Constitution = Constitution + p->Constitution;
            r.Intellectual = Intellectual + p->Intellectual;
            r.Lucky = Lucky + p->Lucky;
            r.Charisma = Charisma + p->Charisma;

            r.MaxEncumbered = MaxEncumbered + p->MaxEncumbered;
            r.MaxHealthPoint = MaxHealthPoint + p->MaxHealthPoint;
            r.HealthRecover = HealthRecover + p->HealthRecover;
            r.AbilityPower = AbilityPower + p->AbilityPower;
            r.MaxAbilityPoint = MaxAbilityPoint + p->MaxAbilityPoint;
            r.AbilityRecover = AbilityRecover + p->AbilityRecover;
            r.AttackRange = AttackRange + p->AttackRange;
            r.AttackSpeed = AttackSpeed + p->AttackSpeed;
            r.AttackInterval = AttackInterval + p->AttackInterval;
            r.MinMeleeAttack = MinMeleeAttack + p->MinMeleeAttack;
            r.MaxMeleeAttack = MaxMeleeAttack + p->MaxMeleeAttack;
            r.MinRangeAttack = MinRangeAttack + p->MinRangeAttack;
            r.MaxRangeAttack = MaxRangeAttack + p->MaxRangeAttack;
            r.Resistance = Resistance + p->Resistance;
            r.Penetration = Penetration + p->Penetration;
            r.Armor = Armor + p->Armor;
            r.Block = Block + p->Block;
            r.Dodge = Dodge + p->Dodge;
            r.Hit = Hit + p->Hit;
            r.CritRate = CritRate + p->CritRate;
            r.CritRatio = CritRatio + p->CritRatio;
            r.Resilience = Resilience + p->Resilience;
            r.ExtraDamage = ExtraDamage + p->ExtraDamage;
            
            r.MaxTroops = MaxTroops + p->MaxTroops;
            r.MoveSpeed = MoveSpeed + p->MoveSpeed;
            return r;
        }

        public static PropertyInfo operator +(PropertyInfo a, PropertyInfo* b) => a.Add(b);
        public static PropertyInfo operator +(PropertyInfo a, PropertyInfo b) => a.Add(&b);
        public PropertyInfo Subtract(PropertyInfo* p) => this + -(*p);
        public static PropertyInfo operator -(PropertyInfo a, PropertyInfo b) => a + (-b);
    }
}